home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / sos3-2.lha / src / agg / Bag.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  28KB  |  789 lines

  1. /* --------------------------------------------------------------------------
  2.  * Copyright 1992 by Forschungszentrum Informatik (FZI)
  3.  *
  4.  * You can use and distribute this software under the terms of the licence
  5.  * you should have received along with this program.
  6.  * If not or if you want additional information, write to
  7.  * Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
  8.  * D-7500 Karlsruhe 1, Germany.
  9.  * --------------------------------------------------------------------------
  10.  */
  11. // **************************************************************************
  12. // Module Bag                       03/07/89           Bernhard Schiefer (bs)
  13. //                                                    modified:   9/8/90 (ja)
  14. //                                                              24/10/91 (bs)
  15. // **************************************************************************
  16. // implements methods of classes: Bag
  17. // **************************************************************************
  18.  
  19. #include "agg_err.h"
  20. #include "trc_agg.h"
  21. #include "sys.h"
  22.  
  23. #include "agg_sos.h"
  24.  
  25. /*
  26. Ein Bag ist eine Erweiterung von Set, eingetragene Objekte koennen auch in 
  27. mehrfachen Exemplaren eingetragen werden.
  28. Die Implementierung setzt auf einem Mapping auf, und zwar wird eine Abbildung
  29. von einem Objekt auf eine Zahl benutzt. Die Zahl gibt die Anzahl an, wieviel 
  30. Exemplare dieses Objekts im Bag sind. Die Moeglichkeit im Schema ein 
  31. Object_sos_Int_Mapping zu benutzen wurde verworfen, stattdessen wird das
  32. ordinaere Mapping benutzt, wobei ein Entity als Zahl sos_Interpretiert wird.
  33. Der Container liegt nutzlos auf der Platte.
  34. */
  35.  
  36. // **************************************************************************
  37. void sos_Object_Bag::search_succ_pred (sos_Bag_node bn,  Index steps, 
  38.                        sos_Object& o, sos_Int& no, sos_Int& max)
  39. // **************************************************************************
  40. // suche ausgehend von dem Element in bag_node steps Schritte nach vorne
  41. // bzw. hsos_Inten. Liefere in o,no,max die neue Position. Ist die 
  42. // Position nicht gueltig, so ist o = my_no_object
  43. {
  44.    sos_Object_sos_Int_Mapping m = self.get_m();
  45.    sos_Cursor cur = m.open_cursor();
  46.  
  47.    max = bn.get_tag_max();
  48.    no = bn.get_tag_no();
  49.    o = bn.get_key_val();
  50.    sos_Object my_no_object = m;
  51.  
  52.    m.move_cursor (cur, o);
  53.  
  54.    for (;o != my_no_object AND steps != 0; )
  55.    {  if (steps > 0)
  56.       {  // Muss ich aufs naechste Element gehen ?
  57.          if (no+steps > max)
  58.          {  // Ja
  59.             if (m.to_succ (cur))
  60.             {  o = m.get_key (cur);
  61.                steps -= (max-no+1);
  62.                no = 1;
  63.                max =  m.get_info (cur);
  64.             }
  65.             else
  66.                o = my_no_object; 
  67.          }
  68.          else
  69.          {  // Nein
  70.             no += steps;
  71.             steps = 0;
  72.          }
  73.       }
  74.       else
  75.       {  // muss ich aufs fruehere Element gehen ?
  76.          if (steps+no < 1)
  77.          {  // Ja
  78.             if (m.to_pred (cur))
  79.             {  o = m.get_key (cur);
  80.                steps += no;
  81.                max = m.get_info (cur);
  82.                no = max;
  83.             }
  84.             else
  85.                o = my_no_object; 
  86.             // Im Augenblick steht der Zeiger auf der letzten 
  87.             // Auspraegung des Objects
  88.          }
  89.          else
  90.          {  // Nein
  91.             no += steps;
  92.             steps = 0;
  93.          }
  94.       }
  95.    } // for
  96. } // sos_Object_Bag::search_succ_pred
  97.  
  98.  
  99. // **************************************************************************
  100. void sos_Object_Bag::write_current (sos_Cursor c,
  101.                                     sos_Object o,
  102.                                     sos_Int    no,
  103.                                     sos_Int    max)
  104. // **************************************************************************
  105. // schreibe in den Cursor die Position auf dem sos_Object o,
  106. // der Exemplarnummer no und der Exemplaranzahl max.
  107. {
  108.    sos_Bag_node               bn = sos_Bag_node::make (c.get_current());
  109.    sos_Object_sos_Int_Mapping m  = self.get_m();
  110.  
  111.    bn.set_key_val (o);
  112.    bn.set_tag_no (no);
  113.    bn.set_tag_max (max);
  114. } // sos_Object_Bag::write_current
  115.  
  116. // **************************************************************************
  117. sos_Int sos_Object_Bag::get_no_of_elements (sos_Object_sos_Int_Mapping m,
  118.                                             sos_Object                 o)
  119. // **************************************************************************
  120. // liefert die Anzahl der Vorkommen, die im Mapping m vom Objekt o sind
  121. {
  122.    if (m.is_key (o))
  123.       return m[o];
  124.    else
  125.       return 0;
  126. } // ** sos_Object_Bag::get_no_of_element
  127.  
  128. // **************************************************************************
  129. sos_Int sos_Object_Bag::set_no_of_elements (sos_Object_sos_Int_Mapping m,
  130.                                             sos_Object o,
  131.                                             sos_Int old_no,
  132.                                             sos_Int new_no)
  133. // **************************************************************************
  134. // Setzt die Anzahl der Vorkommen von o von vormals old_no auf new_no
  135. // Es wird die Anzahl zurueckgeliefert, die dazukam
  136. {
  137.    if ((new_no == 0) AND (old_no >0))
  138.    {
  139.      m.remove (o);
  140.      return -old_no;
  141.    }
  142.    else
  143.       // Hier ist new_no>0 oder old_no==0
  144.       if ((new_no > 0) AND (old_no != new_no))
  145.       {
  146.          m.insert (o, new_no);
  147.          return new_no - old_no;
  148.       }
  149.       else 
  150.       // Hier ist old_no==new_no => nichts
  151.          return 0;
  152. } //  ** sos_Object_Bag::set_no_of_elements
  153.  
  154.  
  155. // **************************************************************************
  156. void sos_Object_Bag::local_initialize (sos_Object_Bag bag)
  157. // **************************************************************************
  158. {  T_PROC ("sos_Object_Bag::local_initialize");
  159.    TT (agg_H, T_ENTER);
  160.  
  161.    bag.set_cardinality (0);
  162.    bag.set_m (sos_Object_sos_Int_Mapping::create
  163.           (bag.container(),
  164.            bag.get_list_cursor(),
  165.            bag.get_based_on_equal()));
  166.  
  167.    TT (agg_H, T_LEAVE);
  168. } // ** local_initialize **
  169.  
  170. // **************************************************************************
  171. void sos_Object_Bag::local_finalize (sos_Object_Bag bag)
  172. // **************************************************************************
  173. {  T_PROC ("sos_Object_Bag::local_finalize");
  174.    TT (agg_H, T_ENTER);
  175.  
  176.    bag.get_m().destroy();
  177.  
  178.    TT (agg_H, T_LEAVE);
  179. } // ** local_finalize **
  180.  
  181. // **************************************************************************
  182. sos_Int sos_Object_Bag::entity_occurs (sos_Cursor c)
  183. // **************************************************************************
  184. {  T_PROC ("sos_Object_Bag::entity_occurs");
  185.    TT (agg_H, T_ENTER);
  186.  
  187.    sos_Int no_of_entries = self.get_m().get_info (c);
  188.  
  189.    TT (agg_H, T_LEAVE);
  190.    return no_of_entries;
  191. } // ** sos_Object_Bag::entity_occurs (sos_Cursor)
  192.  
  193. // **************************************************************************
  194. sos_Bool sos_Object_Bag::to_diff_succ (sos_Cursor c, Index steps)
  195. // **************************************************************************
  196. {  T_PROC ("sos_Object_Bag::to_diff_succ");
  197.    TT (agg_H, T_ENTER);
  198.  
  199.    sos_Object_sos_Int_Mapping m = self.get_m();
  200.    err_assert (c.defined_for (m), "sos_Object_Bag:to_diff_succ");
  201.    err_assert (self.is_valid (c),"sos_Object_Bag:to_diff_succ");   
  202.       
  203.    sos_Bag_node bn = sos_Bag_node::make (c.get_current());
  204.    sos_Bool valid = m.to_succ (c, steps);
  205.    if (valid)
  206.    {  bn.set_tag_no(1);
  207.       bn.set_tag_max (m.get_info (c));
  208.    }
  209.    
  210.    TT (agg_H, T_LEAVE);
  211.    return valid;
  212. } // ** sos_Object_Bag::to_diff_succ **
  213.  
  214. // **************************************************************************
  215. sos_Bool sos_Object_Bag::to_diff_pred (sos_Cursor c, Index steps)
  216. // **************************************************************************
  217. {  T_PROC ("sos_Object_Bag::to_diff_pred");
  218.    TT (agg_H, T_ENTER);
  219.  
  220.    sos_Object_sos_Int_Mapping m = self.get_m();
  221.    err_assert (c.defined_for (m), "sos_Object_Bag:to_diff_pred");
  222.    err_assert (self.is_valid (c),"sos_Object_Bag:to_diff_pred");   
  223.       
  224.    sos_Bag_node bn = sos_Bag_node::make (c.get_current());
  225.    sos_Bool valid = m.to_pred (c, steps);
  226.    if (valid)
  227.    {  sos_Int max = m.get_info (c);
  228.       bn.set_tag_no (max);
  229.       bn.set_tag_max (m.get_info (c));
  230.    }
  231.  
  232.    TT (agg_H, T_LEAVE);
  233.    return valid;
  234. } // ** sos_Object_Bag::to_diff_pred **
  235.  
  236. // **************************************************************************
  237. void sos_Object_Bag::eliminate (sos_Object o)
  238. // **************************************************************************
  239. // loescht alle Vorkommen von o
  240. {
  241.    T_PROC ("sos_Object_Bag::eliminate");
  242.    TT (agg_H, T_ENTER);
  243.  
  244.    sos_Object_sos_Int_Mapping m = self.get_m();
  245.    sos_Int no_of_entries = 0;
  246.  
  247.    if (m.is_key (o))
  248.    {  no_of_entries = m[o];
  249.       m.remove (o);
  250.       self.set_cardinality (self.get_cardinality() - no_of_entries);
  251.    }
  252.  
  253.    TT (agg_H, T_LEAVE);
  254. } // ** sos_Object_Bag::eliminate **
  255.  
  256. // **************************************************************************
  257. sos_Int sos_Object_Bag::occurrences (sos_Object o)
  258. // **************************************************************************
  259.    T_PROC ("sos_Object_Bag::occurrences");
  260.    TT (agg_H, T_ENTER);
  261.  
  262.    sos_Object_sos_Int_Mapping m = self.get_m();
  263.    sos_Int no_of_entries = 0;
  264.  
  265.    if (m.is_key (o))
  266.       no_of_entries = m[o];
  267.  
  268.    TT (agg_H, T_LEAVE);
  269.    return no_of_entries;
  270. } // ** sos_Object_Bag::occurrences (sos_Object)
  271.  
  272. // **************************************************************************
  273. sos_Int sos_Object_Bag::insert (sos_Object o)
  274. // **************************************************************************
  275. // fuege das Objekt o in das Bag ein, es wird die Anzahl der danach (!) im
  276. // Bag vorhandenen Exemplare geliefert.
  277. {
  278.    T_PROC ("sos_Object_Bag::insert");
  279.    TT (agg_H, T_ENTER);
  280.  
  281.    sos_Object_sos_Int_Mapping m = self.get_m();
  282.    sos_Int no_of_entries = 1;
  283.  
  284.    // hole die Abbildung von o, um herauszufinden, wieviel Objekte o
  285.    // schon vorhanden sind
  286.  
  287.    // Der Offset wird sos_Interpretiert als die Anzahl der Objekte o, die schon
  288.    // vorhanden sind.
  289.    if (m.is_key (o))
  290.       no_of_entries = m[o]+1;
  291.  
  292.    m.insert (o, no_of_entries); // ueberschreibe altes o
  293.  
  294.    self.set_cardinality (self.get_cardinality()+1);
  295.    TT (agg_H, T_LEAVE);
  296.    return no_of_entries;
  297. } // ** sos_Object_Bag::insert **
  298.  
  299. // **************************************************************************
  300. sos_Int sos_Object_Bag::remove (sos_Object o)
  301. // **************************************************************************
  302. // loesche ein Objekt o, es wird die Anzahl der Objekte, die 
  303. // vorher (!) im bag waren, zurueckgeliefert
  304. {
  305.    T_PROC ("sos_Object_Bag::remove");
  306.    TT (agg_H, T_ENTER);
  307.  
  308.    sos_Object_sos_Int_Mapping m = self.get_m();
  309.    sos_Int no_of_entries = 0;
  310.  
  311.    if (m.is_key (o))
  312.    {  no_of_entries = m[o];
  313.       if (no_of_entries == 1)
  314.      m.remove (o);
  315.       else
  316.          m.insert (o, no_of_entries-1); 
  317.  
  318.       self.set_cardinality (self.get_cardinality() - 1);
  319.    }
  320.  
  321.    TT (agg_H, T_LEAVE);
  322.    return no_of_entries;
  323. } // ** remove **
  324.  
  325.  
  326. // **************************************************************************
  327. void sos_Object_Bag::operator+= (sos_Object_Bag aset)
  328. // **************************************************************************
  329. // Nach A += B wurden alle Elemente in B zu A aufaddiert
  330. {
  331.    T_PROC ("sos_Object_Bag::operator+=");
  332.    TT (agg_H, T_ENTER);
  333.  
  334.    sos_Object_sos_Int_Mapping this_m = self.get_m();
  335.    sos_Object_sos_Int_Mapping aset_m = aset.get_m();
  336.    sos_Cursor cur = aset_m.open_cursor ();
  337.    for (;aset_m.is_valid (cur);)
  338.    {
  339.       sos_Object o = aset_m.get_key (cur);
  340.       if (aset_m.is_valid (cur) == TRUE)
  341.          aset_m.to_succ (cur);
  342.       sos_Int this_entries = self.get_no_of_elements (this_m, o);
  343.       sos_Int aset_entries = self.get_no_of_elements (aset_m, o);
  344.       sos_Int add=self.set_no_of_elements (this_m, o, 
  345.                        this_entries, this_entries+aset_entries);
  346.       self.set_cardinality (self.get_cardinality()+add);
  347.    } // for
  348.    aset_m.close_cursor (cur);
  349.    TT (agg_H, T_LEAVE);
  350. } // ** _sos_Object_Bag:;operator+= **
  351.  
  352. // **************************************************************************
  353. void sos_Object_Bag::operator-= (sos_Object_Bag aset)
  354. // **************************************************************************
  355. // Nach A -= B wurden aus A alle Elemente, die in B sind, entfernt
  356. {  T_PROC ("sos_Object_Bag::operator-=");
  357.    TT (agg_H, T_ENTER);
  358.  
  359.    sos_Object_sos_Int_Mapping this_m = self.get_m();
  360.    sos_Object_sos_Int_Mapping aset_m = aset.get_m();
  361.  
  362.    sos_Cursor cur = aset_m.open_cursor();
  363.  
  364.    for (;(aset_m.is_valid (cur));)
  365.    {  sos_Object o = aset_m.get_key (cur);
  366.       if (aset_m.is_valid (cur))
  367.          aset_m.to_succ (cur);
  368.  
  369.       // Wie oft gibt`s das Element ?
  370.       sos_Int this_entries = self.get_no_of_elements (this_m, o);
  371.       sos_Int aset_entries = self.get_no_of_elements (aset_m, o);
  372.       sos_Int new_entries = this_entries-aset_entries;
  373.       if (new_entries < 0)
  374.          new_entries = 0;
  375.       
  376.       sos_Int add = self.set_no_of_elements (this_m, o, this_entries, new_entries);
  377.  
  378.       self.set_cardinality (self.get_cardinality()+add);
  379.    } // for
  380.    aset_m.close_cursor (cur);
  381.    TT (agg_H, T_LEAVE);
  382. } // ** _sos_Object_Bag:;operator-= **
  383.  
  384. // **************************************************************************
  385. void sos_Object_Bag::operator*= (sos_Object_Bag aset)
  386. // **************************************************************************
  387. // Liefert die Schnittmenge von A und B,
  388. // Also entferne aus self alle Elemente, die nicht in aset sind
  389. {  
  390.    T_PROC ("sos_Object_Bag::operator*=");
  391.    TT (agg_H, T_ENTER);
  392.  
  393.  
  394.    sos_Object_sos_Int_Mapping aset_m = aset.get_m();
  395.    sos_Object_sos_Int_Mapping this_m = self.get_m();
  396.    sos_Cursor cur = this_m.open_cursor();
  397.    sos_Bool cur_valid = this_m.is_valid (cur); 
  398.    sos_Int length = self.get_cardinality();
  399.    for (;(cur_valid);)
  400.    {  sos_Object o = this_m.get_key (cur);
  401.       // erhoehe gleich den Cursor, da das sos_Object in set_no_of_element 
  402.       // eventuel geloescht wird. Wuerde dann to_succ aufgerufen, 
  403.       // gaebe es den altbekannten SEGV
  404.       if (cur_valid)
  405.          cur_valid = this_m.to_succ (cur);
  406.  
  407.       // Wieviel Auspraegungen von diesem Element gibt es ?
  408.       sos_Int this_entries = self.get_no_of_elements (this_m, o);
  409.       sos_Int aset_entries = self.get_no_of_elements (aset_m, o);
  410.       // Die neue Anzahl ist das Minimum der beiden
  411.       sos_Int new_entries = this_entries;
  412.       if (this_entries > aset_entries )
  413.          new_entries = aset_entries;
  414.  
  415.       sos_Int add = self.set_no_of_elements (this_m, o, this_entries, new_entries);
  416.       
  417.       length += add;
  418.    } // for 
  419.    self.set_cardinality (length);
  420.    this_m.close_cursor (cur);
  421.    TT (agg_H, T_LEAVE);
  422. } // ** sos_Object_Bag::operator*= **
  423.  
  424. // **************************************************************************
  425. sos_Bool sos_Object_Bag::operator< (sos_Object_Bag aset)
  426. // **************************************************************************
  427. // Liefert TRUE zurueck, wenn jedes Element aus this auch in aset ist
  428. // und aset mindestens ein Element mehr enthaelt
  429.    T_PROC ("sos_Object_Bag::operator<");
  430.    TT (agg_H, T_ENTER);
  431.  
  432.    sos_Object_sos_Int_Mapping aset_m = aset.get_m();
  433.    sos_Object_sos_Int_Mapping this_m = self.get_m();
  434.  
  435.    // pruefe zuerst, ob die Anzahl der Elemente schon ein Ergebnis liefert
  436.    if (self.get_cardinality() >= aset.get_cardinality())
  437.    {
  438.       TT (agg_H, T_LEAVE);
  439.       return FALSE;
  440.    }
  441.    
  442.    // So, ab hier sind in aset mehr Elemente als in this
  443.  
  444.    sos_Cursor cur = this_m.open_cursor();
  445.    for (;this_m.is_valid (cur);this_m.to_succ (cur))
  446.    {  sos_Object o = this_m.get_key (cur);
  447.       sos_Int this_entries = self.get_no_of_elements (this_m, o);
  448.       sos_Int aset_entries = self.get_no_of_elements (aset_m, o);
  449.       if (this_entries > aset_entries)
  450.       {
  451.          this_m.close_cursor (cur);
  452.          TT (agg_H, T_LEAVE);
  453.          return FALSE;
  454.       }
  455.    } // for
  456.    this_m.close_cursor (cur);
  457.  
  458.    // Hier angekommen, ist this < aset
  459.    TT (agg_H, T_LEAVE);
  460.    return TRUE;
  461. } // ** sos_Object_Bag::operator< **
  462.  
  463. // **************************************************************************
  464. sos_Bool sos_Object_Bag::operator<= (sos_Object_Bag aset)
  465. // **************************************************************************
  466. // Liefert TRUE zurueck, wenn jedes Element aus this auch in aset ist
  467.    T_PROC ("sos_Object_Bag::operator<=");
  468.    TT (agg_H, T_ENTER);
  469.  
  470.    sos_Object_sos_Int_Mapping aset_m = aset.get_m();
  471.    sos_Object_sos_Int_Mapping this_m = self.get_m();
  472.  
  473.    // pruefe zuerst, ob die Anzahl der Elemente schon ein Ergebnis liefert
  474.    if (self.get_cardinality() > aset.get_cardinality())
  475.    {  TT (agg_H, T_LEAVE);
  476.       return FALSE;
  477.    }
  478.  
  479.    // So, ab hier sind in aset mindestens soviele Elemente wie in this
  480.    sos_Cursor cur = this_m.open_cursor();
  481.    for (;this_m.is_valid (cur);this_m.to_succ (cur))
  482.    {  sos_Object o = this_m.get_key (cur);
  483.       sos_Int this_entries = self.get_no_of_elements (this_m, o);
  484.       sos_Int aset_entries = self.get_no_of_elements (aset_m, o);
  485.       if (this_entries > aset_entries)
  486.       {  this_m.close_cursor (cur);
  487.          TT (agg_H, T_LEAVE);
  488.          return FALSE;
  489.       }
  490.    } // for
  491.    this_m.close_cursor (cur);
  492.    TT (agg_H, T_LEAVE);
  493.    return TRUE;
  494. } // ** sos_Object_Bag::operator<= **
  495.  
  496. // **************************************************************************
  497. sos_Bool sos_Object_Bag::operator> (sos_Object_Bag aset)
  498. { return sos_Bool (aset < self); }
  499. // **************************************************************************
  500.  
  501. // **************************************************************************
  502. sos_Bool sos_Object_Bag::operator>= (sos_Object_Bag aset)
  503. { return sos_Bool (aset <= self); }
  504. // **************************************************************************
  505.  
  506. // **************************************************************************
  507. void sos_Object_Bag::max_union (sos_Object_Bag b)
  508. // **************************************************************************
  509. {  T_PROC ("sos_Object_Bag::max_union");
  510.    TT(agg_H, T_ENTER);
  511.  
  512.    sos_Object_sos_Int_Mapping this_m = self.get_m();
  513.    sos_Object_sos_Int_Mapping b_m    = b.get_m();
  514.    sos_Cursor cur     = b_m.open_cursor ();
  515.    for (;b_m.is_valid (cur);)
  516.    {  sos_Object o;
  517.       o = b_m.get_key (cur);
  518.       b_m.to_succ (cur);
  519.       sos_Int this_entries = self.get_no_of_elements (this_m, o);
  520.       sos_Int b_entries = self.get_no_of_elements (b_m, o);
  521.       if (this_entries < b_entries)
  522.       {  sos_Int add = self.set_no_of_elements (this_m, o, this_entries, b_entries);
  523.          self.set_cardinality (self.get_cardinality()+add);
  524.       }
  525.    } // for
  526.    b_m.close_cursor (cur);
  527.    TT (agg_H, T_LEAVE);
  528. } // ** sos_Object_Bag::max_union **
  529.  
  530. // **************************************************************************
  531. void sos_Object_Bag::local_assign (sos_Object_Bag x, sos_Object o)
  532. // **************************************************************************
  533. {  T_PROC ("sos_Object_Bag::local_assign");
  534.    TT(agg_H, T_ENTER);
  535.  
  536.    sos_Object_Bag y = sos_Object_Bag::make (o);
  537.    x.get_m().assign (y.get_m());
  538.  
  539.    x.set_cardinality (y.get_cardinality());
  540.    TT(agg_H, T_LEAVE);
  541. } // sos_Object_Bag::local_assign
  542.  
  543. // **************************************************************************
  544. sos_Bool sos_Object_Bag::local_equal (sos_Object_Bag x,
  545.                                       sos_Object     o,
  546.                       sos_Eq_kind    eq_kind)
  547. // **************************************************************************
  548. {  T_PROC ("sos_Object_Bag::local_equal");
  549.    TT(agg_H, T_ENTER);
  550.    
  551.    sos_Bool result;
  552.  
  553.    if ((eq_kind EQ EQ_STRONG AND NOT o.has_type (x.type())) OR
  554.        (eq_kind EQ EQ_WEAK   AND NOT o.isa (x.type())))
  555.       result = FALSE;
  556.    else
  557.    {  sos_Object_Bag y = sos_Object_Bag::make (o);
  558.       sos_Object_sos_Int_Mapping x_m = x.get_m();
  559.       sos_Object_sos_Int_Mapping y_m = y.get_m();
  560.       if (x.get_cardinality() != y.get_cardinality())
  561.      result = FALSE;
  562.       else
  563.       {  result = TRUE;
  564.      agg_iterate_association (x_m, sos_Object key, sos_Int x_entries)
  565.      {  if (x_entries != y.get_no_of_elements (y_m, key))
  566.         {  result = FALSE;
  567.            break;
  568.         }  
  569.      }
  570.      agg_iterate_association_end (x_m, key, x_entries);
  571.       }
  572.    }
  573.  
  574.    TT(agg_H, T_LEAVE;TB(result));
  575.  
  576.    return result;
  577. } // sos_Object_Bag::local_equal
  578.  
  579. // **************************************************************************
  580. sos_Int sos_Object_Bag::local_hash_value (sos_Object_Bag)
  581. // **************************************************************************
  582. {  T_PROC ("sos_Object_Bag::local_hash_value");
  583.    TT(agg_H, T_ENTER);
  584.    
  585.    sos_Int result = 0;
  586.  
  587.    TT(agg_H, T_LEAVE);
  588.  
  589.    return result;
  590. } // sos_Object_Bag::local_hash_value
  591.  
  592. // **************************************************************************
  593. sos_Bool sos_Object_Bag::is_element (sos_Object o)
  594. // **************************************************************************
  595. {  T_PROC ("sos_Object_Bag::is_element");
  596.    TT (agg_H, T_ENTER);
  597.  
  598.    sos_Bool result = self.get_m().is_key (o);
  599.  
  600.    TT (agg_H, T_LEAVE);
  601.    return result;
  602. } // ** sos_Object_Bag::is_element (sos_Object)
  603.  
  604. // **************************************************************************
  605. sos_Object sos_Object_Bag::get (sos_Cursor c)
  606. // **************************************************************************
  607. {  T_PROC ("sos_Object_Bag::get");
  608.    TT (agg_H, T_ENTER);
  609.  
  610.    err_assert (c.defined_for (self.get_m()), "sos_Object_Bag:get");
  611.    err_assert (self.is_valid (c),"sos_Object_Bag:get");   
  612.  
  613.    sos_Object o = sos_Bag_node::make (c.get_current()).get_key_val();
  614.     
  615.    TT (agg_H, T_LEAVE);
  616.    return o;
  617. } // ** sos_Object_Bag::get **
  618.  
  619. // **************************************************************************
  620. void sos_Object_Bag::remove_at (sos_Cursor c)
  621. // **************************************************************************
  622. {  T_PROC ("sos_Object_Bag::remove_at");
  623.    TT(agg_H, T_ENTER);
  624.  
  625.    err_assert (c.defined_for (self.get_m()), "sos_Object_Bag:remove_at");
  626.    err_assert (self.is_valid (c),"sos_Object_Bag:remove_at");   
  627.  
  628.    sos_Object entity = self.get (c);
  629.    if (self.get_list_cursor())
  630.       self.to_succ (c,1);
  631.    else
  632.       {  sos_Bag_node bn = sos_Bag_node::make (c.get_current());
  633.          sos_Object my_no_object = self.get_m();
  634.          bn.set_key_val (my_no_object);
  635.       }
  636.    self.remove (entity);
  637.  
  638.    TT(agg_H, T_LEAVE);
  639. } // sos_Object_Bag::remove_at
  640.  
  641. // **************************************************************************
  642. sos_Int sos_Object_Bag::card ()
  643. // **************************************************************************
  644. {
  645.    T_PROC ("sos_Object_Bag::card");
  646.    TT (agg_H, T_ENTER);
  647.  
  648.    sos_Int crd = self.get_cardinality();
  649.  
  650.    TT (agg_H, T_LEAVE; TI(crd));
  651.    return crd;
  652. } // ** card **
  653.  
  654. // **************************************************************************
  655. void sos_Object_Bag::clear()
  656. // **************************************************************************
  657. {  T_PROC ("sos_Object_Bag::clear");
  658.    TT (agg_H, T_ENTER);
  659.    
  660.    self.get_m().clear();
  661.    self.set_cardinality(0);
  662.  
  663.    TT (agg_H, T_LEAVE);
  664. } // ** clear
  665.  
  666. // **************************************************************************
  667. sos_Cursor sos_Object_Bag::open_cursor (sos_Container Cursor_ct)
  668. // **************************************************************************
  669. {  sos_Container ct = self.container();
  670.    sos_Object_sos_Int_Mapping m = self.get_m();
  671.    sos_Cursor c = sos_Cursor::create(Cursor_ct, m);
  672.    sos_Bag_node bn = sos_Bag_node::create(Cursor_ct);
  673.  
  674.    c.set_current (bn);
  675.    m.to_first (c);
  676.    if (self.is_valid (c))
  677.    {  bn.set_tag_no(1);
  678.       bn.set_tag_max (m.get_info (c));
  679.    }
  680.  
  681.    return c;
  682. } // sos_Object_Bag::open_cursor
  683.  
  684. // **************************************************************************
  685. void sos_Object_Bag::close_cursor (sos_Cursor c)
  686. // **************************************************************************
  687. {  
  688.    c.get_current().destroy();
  689.    c.destroy();
  690. } // sos_Object_Bag::close_cursor
  691.  
  692. // **************************************************************************
  693. sos_Cursor sos_Object_Bag::duplicate (sos_Cursor c)
  694. // **************************************************************************
  695. {  sos_Container Cursor_ct = c.container();
  696.    sos_Bag_node  bn        = sos_Bag_node::make (c.get_current());
  697.    sos_Cursor dup_c        = sos_Cursor::create(Cursor_ct, self.get_m());
  698.    sos_Bag_node dup_bn     = sos_Bag_node::create(Cursor_ct);
  699.  
  700.    dup_c.set_current (dup_bn);
  701.    dup_bn.set_key_val (bn.get_key_val());
  702.    dup_bn.set_tag_no (bn.get_tag_no());
  703.    dup_bn.set_tag_max (bn.get_tag_max());
  704.    return dup_c;
  705. } // sos_Object_Bag::duplicate
  706.  
  707. // **************************************************************************
  708. sos_Bool sos_Object_Bag::is_valid (sos_Cursor c)
  709. // ************************************************************************** 
  710. {  sos_Bool valid = self.get_m().is_valid (c);
  711.    return valid;
  712. } // ** is_valid **
  713.  
  714. // **************************************************************************
  715. sos_Bool sos_Object_Bag::to_first (sos_Cursor c)
  716. // **************************************************************************
  717. {  sos_Object_sos_Int_Mapping m = self.get_m();
  718.    sos_Bag_node  bn        = sos_Bag_node::make (c.get_current());
  719.    sos_Container Cursor_ct = c.container();
  720.  
  721.    m.to_first (c);
  722.    if (m.is_valid (c))
  723.    { bn.set_tag_no(1);
  724.      bn.set_tag_max (m.get_info (c));
  725.    }
  726.  
  727.    return m.is_valid (c);
  728. } // sos_Object_Bag::to_first
  729.  
  730. // **************************************************************************
  731. sos_Bool sos_Object_Bag::to_last (sos_Cursor c)
  732. // **************************************************************************
  733. {  sos_Object_sos_Int_Mapping m = self.get_m();
  734.    sos_Bag_node  bn = sos_Bag_node::make (c.get_current());
  735.    sos_Container Cursor_ct = c.container();
  736.  
  737.    m.to_last (c);
  738.    if (m.is_valid (c))
  739.    {   sos_Int no = m.get_info (c);
  740.        bn.set_tag_no (no);
  741.        bn.set_tag_max (no);
  742.    }
  743.  
  744.    return m.is_valid (c);
  745. } // sos_Object_Bag::to_last
  746.  
  747. // **************************************************************************
  748. sos_Bool sos_Object_Bag::to_succ (sos_Cursor c, Index steps)
  749. // **************************************************************************
  750. {  T_PROC ("sos_Object_Bag::to_succ");
  751.    TT (agg_H, T_ENTER);
  752.  
  753.    err_assert (c.defined_for (self.get_m()), "sos_Object_Bag:to_succ");
  754.    err_assert (self.is_valid (c),"sos_Object_Bag:to_succ");   
  755.       
  756.    sos_Bag_node bn = sos_Bag_node::make (c.get_current());
  757.    sos_Object   o;
  758.    sos_Int      no, max;
  759.  
  760.    self.search_succ_pred (bn, steps, o, no, max);
  761.    self.write_current (c, o, no, max);
  762.  
  763.    TT (agg_H, T_LEAVE);
  764.    return self.is_valid (c);
  765. } // ** sos_Object_Bag::to_succ **
  766.  
  767. // **************************************************************************
  768. sos_Bool sos_Object_Bag::to_pred (sos_Cursor c, Index steps)
  769. // **************************************************************************
  770. {  T_PROC ("sos_Object_Bag::to_pred");
  771.    TT (agg_H, T_ENTER);
  772.  
  773.    err_assert (c.defined_for (self.get_m()), "sos_Object_Bag:to_pred");
  774.    err_assert (self.is_valid (c),"sos_Object_Bag:to_pred");   
  775.       
  776.    sos_Bag_node bn = sos_Bag_node::make (c.get_current());
  777.    sos_Object   o;
  778.    sos_Int      no, max;
  779.  
  780.    self.search_succ_pred (bn,-steps, o, no, max);
  781.    self.write_current (c, o, no, max);
  782.    
  783.    TT (agg_H, T_LEAVE);
  784.    return self.is_valid (c);
  785. } // ** sos_Object_Bag::to_pred **
  786.